#include <stdio.h> 

 

#include <strings.h> 

 

#include <stdlib.h> 

 

#include "TableSym.h" 

 

 

 

 

 

int address = -1; 

 

int numFct = -1; 

 

int nbArg = 0; 

 

int nbVar = 0; 

 

 

 

 

 

 

 

//créer un noeud pour une nouvelle fonction 

 

FCTSYM createSTNodeFct() 

 

{ 

 

    FCTSYM node = (FCTSYM) malloc(sizeof(FCTSYMNODE)); 

 

    if (node == NULL) { 

 

    fprintf(stderr, "KO\n"); 

 

    printf("ERROR : cannot malloc in createSTNodeFct()\n"); 

 

    exit(1); 

 

    } 

    else

    return node; 

 

} 

 

 

 

 

 

//créer un noeud pour une nouvelle variable 

 

VARSYM createSTNodeVar() 

 

{ 

 

    VARSYM node = (VARSYM) malloc(sizeof(VARSYMNODE)); 

 

    if (node == NULL) { 

 

    fprintf(stderr, "KO\n"); 

 

    printf("ERROR : cannot malloc in createSTNodeFct()\n"); 

 

    exit(1); 

 

    } 

 

     

 

    return node; 

 

} 

 

 

 

 

 

//Créer la table des symboles (créer le premier noeud de fonction) 

 

FCTSYM createSymTable() 

 

{ 

 

    FCTSYM symFct = (FCTSYM) createSTNodeFct(NULL, NULL, "Root", NULL, 0, -1); 

 

    return symFct; 

 

} 

 

 

 

 

 

//ajouter une fonction à la table des symboles 

 

FCTSYM addFctToSymTable(FCTSYM parentFct, TREE locationOnTree, char *name, char *retType, int isMain, int level) 

 

{ 

 

    FCTSYM node; 

 

    node = createSTNodeFct(); 



    if (parentFct != NULL)    //cas d'une fonction imbriquée dans une autre 

 

    { 

 

    node->parentFct = parentFct; 

 

    node->next = parentFct->childFct; 

 

    node->prev = NULL; 

 

    node->childFct = NULL; 

 

    if (parentFct->childFct != NULL)    //si parentFct est la racine, son child est NULL 

 

    { 

 

        parentFct->childFct->prev = node; 

 

    } 

 

    parentFct->childFct = node;    //on ajoute le noeud aux fils de la fonction parente 

 

    } 

 

 

 

    else            //pour la première cellule (racine) 

 

    { 

 

    node->next = NULL; 

 

    node->prev = NULL; 

 

    node->parentFct = NULL; 

 

    node->childFct = NULL; 

 

    } 

 

    node->name = name; 

 

    node->retType = retType; 

 

    node->level = level; 

 

    node->numFct = numFct; 

 

    node->locationOnTree = locationOnTree; 

 

    node->isMain = isMain; 

 

    node->nextVar = NULL; 

 

    return node; 

 

} 

 

 

 

 

 

//ajouter une variable à la table des symboles 

 

VARSYM addVarToSymTable(FCTSYM fct, TREE locationOnTree, char *name, char *type, int level, int varMode) 

{ 

 

    VARSYM node = createSTNodeVar(); 



    node->name = name; 

 

    node->type = type; 

 

    node->varMode = varMode; 

 

    node->fct = fct; 

 

    node->level = level; 

 

    if (fct->nextVar != NULL) { 

 

    node->next = fct->nextVar; 

 

    fct->nextVar->prev = node; 

 

    } 

 

 

 

    else { 

 

    node->next = NULL; 

 

    } 

 

    fct->nextVar = node; 

 

    node->prev = NULL; 

 

    node->locationOnTree = locationOnTree; 

 

    node->address = address;

 

    return node; 

 

} 

 

 

 

 

 

//chercher les variables 

 

void fillSymTableWithVariable(FCTSYM fct, TREE tree, int level, char *type) 

{ 

 

    if (tree != NULL) { 

 

 

 

    //chercher les variables qui se trouvent dans la partie declarations 

 

    if (tree->type == AT_DECL) { 

 

        fillSymTableWithVariable(fct, tree->left, level, NULL); 

 

    } 

 

    if (tree->type == AT_ILISTDECL) { 

 

        fillSymTableWithVariable(fct, tree->left, level, NULL); 

 

        fillSymTableWithVariable(fct, tree->middle, level, NULL); 

 

    } 

 

    if (tree->type == AT_INT) { 

 

        fillSymTableWithVariable(fct, tree->left, level, "int"); 

 

    } 

 

    if (tree->type == AT_BOOL) { 

 

        fillSymTableWithVariable(fct, tree->left, level, "bool"); 

 

    } 

 

    if (tree->type == AT_MATRIX) { 

 

        fillSymTableWithVariable(fct, tree->left, level, "matrix"); 

 

    } 

 

    if (tree->type == AT_LISTVAR) { 

 

        fillSymTableWithVariable(fct, tree->left, level, type); 

 

        fillSymTableWithVariable(fct, tree->middle, level, type); 

 

    } 

 

    if (tree->type == AT_ID) { 

 

        if (!alreadyIsSymbolVar(fct, tree->name))    //on ajoute la variable uniquement si il n'existe pas d'autre variable ayant le même nom dans la fonction 

 

        { 

 

        address++; 

 

        VARSYM var; 

 

        var = 

 

            addVarToSymTable(fct, tree, tree->name, type, level, 

 

                     -1); 

 

        nbVar++; 

 

        fct->nbVar = nbVar; 

 

        } 

 

    } 

 

    } 

 

} 

 

 

 

 

 

//chercher les arguments d'une fonction 

 

void fillSymTableWithArgument(FCTSYM fct, TREE tree, int level, char *type, int varMode) 

{ 

 

    if (tree != NULL) { 

 

    if (tree->type == AT_LISTARG) { 

 

        fillSymTableWithArgument(fct, tree->left, level, type, 

 

                     varMode); 

 

        if (tree->middle != NULL) { 

 

        fillSymTableWithArgument(fct, tree->middle, level, 

 

                     type, varMode); 

 

        } 

 

    } 

 

    if (tree->type == AT_ARGVARINT) { 

 

        fillSymTableWithArgument(fct, tree->left, level, "int", 1); 

 

    } 

 

    if (tree->type == AT_ARGINT) { 

 

        fillSymTableWithArgument(fct, tree->left, level, "int", 0); 

 

    } 

 

    if (tree->type == AT_ARGVARBOOL) { 

 

        fillSymTableWithArgument(fct, tree->left, level, "bool", 1); 

 

    } 

 

    if (tree->type == AT_ARGBOOL) { 

 

        fillSymTableWithArgument(fct, tree->left, level, "bool", 0); 

 

    } 

 

    if (tree->type == AT_ARGVARMATRIX) { 

 

        fillSymTableWithArgument(fct, tree->left, level, "matrix", 1); 

 

    } 

 

    if (tree->type == AT_ARGMATRIX) { 

 

        fillSymTableWithArgument(fct, tree->left, level, "matrix", 0); 

 

    } 

 

    if (tree->type == AT_ID) { 

 

        if (!alreadyIsSymbolVar(fct, tree->name))    //on ajoute la variable (argument) uniquement si il n'existe pas d'autre variable ayant le même nom dans la fonction 

 

        { 

 

        VARSYM arg; 

 

        address++; 

 

        arg = 

 

            addVarToSymTable(fct, tree, tree->name, type, level, 

 

                     varMode); 

 

        nbArg++; 

 

        fct->nbArguments = nbArg; 

 

        } 

 

    } 

 

    } 

 

} 

 

 

 

 

 

//pour remplir la table des symboles avec des fonctions (appel sur root) 

 

void fillSymTableWithFonction(FCTSYM lastAddedFct, TREE tree, int level, char *nameMain) 

{ 

 

    if (tree->type == AT_ROOT) { 

 

    level++; 

 

    fillSymTableWithFonction(lastAddedFct, tree->middle, level, 

 

                 nameMain); 

 

    } 

 

    if (tree->type == AT_LISTFCT) { 

 

    fillSymTableWithFonction(lastAddedFct, tree->left, level, 

 

                 nameMain); 

 

    fillSymTableWithFonction(lastAddedFct, tree->middle, level, 

 

                 nameMain); 

 

    } 

 

    if (tree->type == AT_FCT) { 

 

    FCTSYM newFct; 

 

    if (lastAddedFct == NULL) { 

 

        printf 

 

        ("lose: fonction déjà présente!!!!!!!!!!!!!!!!!!!!!!!!!\n"); 

 

    } 

 

 

 

    else { 

 

        if ((level == 1) && (strcmp(tree->name, nameMain) == 0))    // trouver la fonction Main 

 

        { 

 

        if (!alreadyIsSymbolFctInParentFct(lastAddedFct, tree->name))    //vérifier si pas de fonction du même nom déjà présente 

 

        { 

 

            numFct++; 

 

            newFct = 

 

            addFctToSymTable(lastAddedFct, tree, tree->name, 

 

                     tree->middle->name, 1, level); 

 

        } 

 

        } 

 

 

 

        else { 

 

        if (!alreadyIsSymbolFctInParentFct(lastAddedFct, tree->name))    //vérifier si pas de fonction du même nom déjà présente 

 

        { 

 

            numFct++; 

 

            newFct = 

 

            addFctToSymTable(lastAddedFct, tree, tree->name, 

 

                     tree->middle->name, 0, level); 

 

        } 

 

        } 

 

        fillSymTableWithFonction(newFct, tree->right, level, nameMain);    //pour les fonctions a un niveau encore inferieur 

 

        address = -1; 

 

        fillSymTableWithVariable(newFct, tree->right, level, NULL);    //la partie declaration d'une fonction se trouve dans le noeud de droite 

 

        fillSymTableWithArgument(newFct, tree->left, level, NULL, 0); 

 

        nbArg = 0; 

 

        nbVar = 0; 

 

    } 

 

    } 

 

    if (tree->type == AT_DECL) { 

 

    level++; 

 

    if (tree->left != NULL) { 

 

        fillSymTableWithFonction(lastAddedFct, tree->left, level, 

 

                     nameMain); 

 

    } 

 

    } 

 

    if (tree->type == AT_ILISTDECL) { 

 

    if (tree->left != NULL) { 

 

        fillSymTableWithFonction(lastAddedFct, tree->left, level, 

 

                     nameMain); 

 

    } 

 

    if (tree->middle != NULL) { 

 

        fillSymTableWithFonction(lastAddedFct, tree->middle, level, 

 

                     nameMain); 

 

    } 

 

    } 

 

} 

 

 

 

int alreadyIsSymbolFctInParentFct(FCTSYM symFct, char *name) 

{ 

 

    return (searchFctAtParentFct(symFct, name) == NULL) ? 0 : 1;    //on vérifie si une fonction de même nom est déjà présente dans la même fonction parente 

 

} 

 

 

 

int alreadyIsSymbolVar(FCTSYM symFct, char *name) 

{ 

 

    return (searchVarAtFct(symFct, name) == NULL) ? 0 : 1;    //on vérifie si une variable de même nom est déjà présente uniquement dans la même fonction 

 

} 

 

 

 

 

 

//afficher la liste des variable d'une fonction 

 

void printSymbolVar(VARSYM varSym) 

{ 

 

    if (varSym != NULL) { 

 

    if (varSym->varMode == -1) { 

 

        printf 

 

        ("; Variable: [%p] name=%s ,level=%d, fonction englobante=%s, type=%s, adresse locale=%d, locationOnTree=    [%p], next=%p, prev=%p,  \n", 

 

         varSym, varSym->name, varSym->level, 

 

         varSym->fct->name, varSym->type, varSym->address, 

 

         varSym->locationOnTree, varSym->next, varSym->prev); 

 

    } 

 

 

 

    else { 

 

        printf 

 

        ("; Argument: [%p] name=%s ,level=%d, fonction englobante=%s, type=%s, adresse locale=%d, locationOnTree=    [%p], next=%p, prev=%p, varMode=%d \n", 

 

         varSym, varSym->name, varSym->level, 

 

         varSym->fct->name, varSym->type, varSym->address, 

 

         varSym->locationOnTree, varSym->next, varSym->prev, 

 

         varSym->varMode); 

 

    } 

 

    printSymbolVar(varSym->next); 

 

    } 

 

} 

 

 

 

 

 

//afficher la table des symbole complète 

 

void printSymbolTable(FCTSYM symFct) 

{ 

 

    if (symFct != NULL) { 

 

    printf 

 

        ("; Fonction: [%p] name= %s , level=%d, numFct=%d, nbArgs=%d, nbVar = %d, locationOnTree=[%p], next=%p , prev=%p , child=%p , parent=%p, nextVar = %p \n", 

 

         symFct, symFct->name, symFct->level, symFct->numFct, 

 

         symFct->nbArguments, symFct->nbVar, symFct->locationOnTree, 

 

         symFct->next, symFct->prev, symFct->childFct, 

 

         symFct->parentFct, symFct->nextVar); 

 

    if (symFct->nextVar != NULL) { 

 

        printSymbolVar(symFct->nextVar); 

 

    } 

 

    printSymbolTable(symFct->childFct); 

 

    printSymbolTable(symFct->next); 

 

    } 

 

} 

 

 

 

 

 

//libérer l'espace des noeuds de fonctions 

 

void freeSymTableFct(FCTSYM fctSym) 

{ 

 

    if (fctSym != NULL) { 

 

    if (fctSym->name != NULL) 

 

        free(fctSym->name); 

 

    if (fctSym->retType != NULL) 

 

        free(fctSym->retType); 

 

    freeSymTableFct(fctSym->next); 

 

    freeSymTableVar(fctSym->nextVar); 

 

    free(fctSym); 

 

    } 

 

} 

 

 

 

 

 

//libérer l'espace des noeuds de variables 

 

void freeSymTableVar(VARSYM varSym) 

{ 

 

    if (varSym != NULL) { 

 

    if (varSym->name != NULL) 

 

        free(varSym->name); 

 

    freeSymTableVar(varSym->next); 

 

    free(varSym); 

 

    } 

 

} 

 

 

 

VARSYM searchVarAtFct(FCTSYM fct, char *name) 

{ 

 

    VARSYM p; 

 

    p = fct->nextVar; 

 

    while (p != NULL) { 

 

    if (strcmp(p->name, name) == 0) { 

 

        return p; 

 

    } 

 

 

 

    else { 

 

        p = p->next; 

 

    } 

 

    } 

 

    return NULL;        // la variable 'name' n'est pas déclarée dans fct 

 

} 

 

VARSYM searchVarAtFctByPos(FCTSYM fct, int pos) 

{ 

    VARSYM p; 

    p = fct->nextVar; 

    while(pos>1) 

    { 

    p = p->next; 

    pos--; 

    } 

    return p; 

 

} 

 

 

 

FCTSYM searchFctAtParentFct(FCTSYM fct, char *name) 

{ 

 

    FCTSYM f; 

 

    f = fct->childFct; 

 

    while (f != NULL) { 

 

    if (strcmp(f->name, name) == 0) { 

 

        return f; 

 

    } 

 

 

 

    else { 

 

        f = f->next; 

 

    } 

 

    } 

 

    return NULL;        // la variable 'name' n'est pas déclarée dans fct 

 

} 

 

void printVariable(VARSYM v, int nb) 

{

	if (v != NULL) {

		printf("\"p%p\"  [label = \" <f0> name = %s | <f1> type = %s | <f2> next | <f3> prev \"shape =\"record\"] ; \n", v, v->name, v->type);

		

		if(v->next != NULL) 

		{

			printf("\"p%p\":f2 -> \"p%p\":f2 ; \n", v, v->next);

		}

		if(v->prev != NULL) 

		{

			printf("\"p%p\":f3 -> \"p%p\":f3 ; \n", v, v->prev);

		}

		

		

		printVariable(v->next,nb+1);		

	}

} 

 

void printSymTableForDia(FCTSYM fct, int nb)

{

	if (fct != NULL){

		printf("\"p%p\"  [label = \" <f0> next = [%p] | <f1> prev = [%p] |<f2> name = %s |<f3> retType = %s |<f4> locationOnTree=[p%p]|<f5> level = %d |<f6> isMain = %d | numFct = %d |<f7> nbArguments = %d |<f8> nbVar = %d | <f9> childFct = [%p] | <f10> parentFct = [%p] | <f11> nextVar \"shape =\"record\"] ; \n", fct, fct->next, fct->prev, fct->name, fct->retType, fct->locationOnTree, fct->level,fct->isMain, fct->numFct, fct->nbArguments, fct->nbVar, fct->childFct, fct->parentFct, fct->nextVar);

	

	if (fct->nextVar != NULL) {

		printf("\"p%p\":f11 -> \"p%p\" \n", fct, fct->nextVar);

		printVariable(fct->nextVar, 0); 

	}

	

		if (fct->next != NULL)

			printf("\"p%p\":f0 -> \"p%p\":f0 \n", fct, fct->next);

		if (fct->prev != NULL)

			printf("\"p%p\":f1 -> \"p%p\":f1 \n", fct, fct->prev);

		if (fct->childFct != NULL)

			printf("\"p%p\":f9 -> \"p%p\" \n", fct, fct->childFct);

		if (fct->parentFct != NULL)

			printf("\"p%p\":f10 -> \"p%p\" \n", fct, fct->parentFct);



	printSymTableForDia(fct->next, nb+1);

	printSymTableForDia(fct->childFct, nb+1);

	}		

}

 


